package simulateOS.management.process;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import simulateOS.controller.ProcessPageController;
import simulateOS.entity.Process;
import simulateOS.entity.Status;
import simulateOS.utils.RuntimeTimer;

import java.util.*;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

@Slf4j
@Component
public class Blocking_supervisor implements Runnable{
    //监控阻塞表的线程类

    @Autowired
    private ProcessPageController processPageController;

    @Autowired
    private RuntimeTimer runtimeTimer;

    private static Blocking_supervisor supervisor = null;

    private boolean isRun = true;

    //分化界面内的阻塞队列，获得真正的阻塞进程
    public List<Process> blockList = new ArrayList<>();
    //分化界面内的阻塞队列，获得等待就绪的进程
    public List<Process> waitingReadyList = new ArrayList<>();
    //分化界面内的阻塞队列，获得等待设备的进程
    public List<Process> waitingDeviceList = new ArrayList<>();


    //单例，确保线程独一无二
    public Blocking_supervisor BlockSupervisor(){
        if(supervisor == null){
            supervisor = new Blocking_supervisor();
            log.info("新建监控线程成功");
        }
        return supervisor;
    }

    private Blocking_supervisor() {

    }

    public Blocking_supervisor getSupervisor() {
        return supervisor;
    }

    private void superviseBlockList() {
        //分化阻塞队列
        splitBlockProcessList();
        //先跑阻塞态进程，再跑等待态进程
        Double now_time = runtimeTimer.getCurTime();
        for(Process p:blockList) {
            ((ProcessRunner) p).runDevice(now_time);
        }
        //更新可能改变状态的进程
        splitBlockProcessList();
        for(Process p:waitingDeviceList) {
            ((ProcessRunner) p).waitDevice();
        }
        //更新可能改变状态的进程
        splitBlockProcessList();
        while(!waitingReadyList.isEmpty()) {
            //等待队列为空就退出循环
//            if(waitingReadyList.isEmpty()) {
//                break;
//            }
            if(processPageController.getReadyProcessList().size()>=10) {
                break;
            }
            ProcessRunner pr = (ProcessRunner) waitingReadyList.remove(0);
            pr.goToReady();
        }
    }

    public void splitBlockProcessList() {
        //清空临时队列
        blockList.clear();
        waitingReadyList.clear();
        waitingDeviceList.clear();
        List<Process> blockingProcessList = processPageController.getBlockingProcessList();
        int size = blockingProcessList.size();
        for(int i=0;i<size;i++) {
            ProcessRunner p = (ProcessRunner) blockingProcessList.get(i);
            if(p.getStatus() == Status.BLOCK) {
                //运行设备而被阻塞的进程
                blockList.add(p);
            }
            else if(p.getStatus() == Status.WAIT) {
                //等待态的进程
                if(((ProcessRunner) p).isNeedDevice()) {
                    //等待设备分配的进程
                    waitingDeviceList.add(p);
                } else {
                    //等待就绪队列的进程
                    waitingReadyList.add(p);
                }

            }
            size = blockingProcessList.size();
        }
    }


//    private void superviseBlockList() {
//        if(processPageController==null) {
//            return;
//        }
//        int size = processPageController.getBlockingProcessList().size();
//        if(size==0) {
//            return;
//        }
//        //创造size()个线程跑阻塞的操作
//        List<Blocker> blockerList = new ArrayList<>();
//        barrier = new CyclicBarrier(size+10);
//        Iterator<Map.Entry<Integer, ProcessRunner>> it = processRunnerBlockList.entrySet().iterator();
//        while(it.hasNext()) {
//            Map.Entry<Integer, ProcessRunner> prMap = it.next();
//            int pcbId = prMap.getKey();
//            ProcessRunner pr = prMap.getValue();
//            int type = 0;
//            if(pr.isNeedDevice()==false) {
//                //等待进入就绪队列
//                type = 0;
//            } else{
//                if(pr.getStatus().getValue().getValue()==2) {
//                    //正常使用设备阻塞
//                    type = 1;
//                } else if(pr.getStatus().getValue().getValue()==4){
//                    //等待使用设备的等待态
//                    type = 2;
//                }
//            }
//            Blocker blocker = new Blocker(pr,type,barrier);
//            blockerList.add(blocker);
//        }
//        for(Blocker b:blockerList) {
//            //逐一开跑进程
//            new Thread(b).start();
//        }
//        try {
//            barrier.await();
//            size = processPageController.getReadyProcessList().size();
//            //让超出列表显示的进程重新阻塞
//            while(processPageController.getReadyProcessList().size()>10) {
//                Process p = processPageController.getReadyProcessList().get(10);
//                p.setStatus(Status.WAIT);
//
//                int pcbId = p.getPcb().getValue().getPid();
//                processPageController.getReadyProcessList().remove(p);
//                ProcessRunner pr = RR_executor.processRunnerReadyList.get(pcbId);
//                RR_executor.processRunnerReadyList.remove(pcbId);
//
//                Blocking_supervisor.processRunnerBlockList.put(pcbId,pr);
//                processPageController.getBlockingProcessList().add(p);
//            }
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        } catch (BrokenBarrierException e) {
//            throw new RuntimeException(e);
//        }
//    }


//    private void superviseWaitingList() {
//        //监控等待态进程
//
//
//    }
//
//    private void superviserunBlockList() {
//        //监控阻塞队列进程
//
//
//    }

    public void destroy() {
        isRun = false;
    }

    @Override
    public void run() {
        while(isRun) {
            superviseBlockList();
            try {
                Thread.sleep(750);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

}
